<?php
class Nodes {

    private $db = false;
    
    public function __construct() {
        global $db;
        $this->db = $db;
    }
    
    public function getOneByName( $name ) {
        $query = 'SELECT id FROM node WHERE name = '.$this->db->quote($name).' LIMIT 1;';
        $result = $this->db->query( $query );
        if ( is_array($result) && count($result) ) {
            return $this->getNode(array_pop(array_pop($result)));
        }
        return false;
    }
    
    public function getByName( $name ) {
        $query = 'SELECT id FROM node WHERE name = '.$this->db->quote($name).';';
        $result = $this->db->query( $query );
        if ( is_array($result) && count($result) ) {
            return $result;
        }
        return false;
    }
    
    public function getByUrlId( $urlId ) {
        $query = 'SELECT node.id AS id FROM node JOIN link ON (link.`to` = '.$urlId.' AND link.relation = '.NODE_URL.' AND link.`from` = node.id) WHERE name = '.$this->db->quote($name).' LIMIT 1;';
        $result = $this->db->query( $query );
        if ( is_array($result) && count($result) ) {
            return $this->getNode(array_pop(array_pop($result)));
        }
        return false;
    }
    
    public function getNode($id) {
        $node = new Node();
        $node->setId($id);
        $node->loadData();
        return $node;
    }
    
    public function nodeChilds($links) {
        foreach ( $links as $i=>$link ) {
            if (isset($link['to'])) {
                $links[$i]['to'] = $this->getNode($link['to']);
            }
            if (isset($link['relation'])) {
                $links[$i]['relation'] = $this->getNode($link['relation']);
            }
            if (isset($link['from'])) {
                $links[$i]['from'] = $this->getNode($link['from']);
            }
            if (isset($link['id'])) {
                $links[$i] = $this->getNode($link['id']);
            }
        }
        return $links;
    }
    
    public function getLatest($limit) {
        $query = 'SELECT id FROM node ORDER BY id DESC LIMIT '.$limit;
        return $this->db->query($query);
    }
    
    public function getLinksFrom($node_id) {
        $query = 'SELECT `to` AS id FROM link WHERE link.`from` = '.$this->db->quote($node_id).' AND `value` >= '.$this->db->quote(LINK_MIN).' ORDER BY `value` DESC LIMIT 50';
        return $this->db->query($query);
    }
    
    public function getLinksTo($node_id) {
        $query = '`from` AS id FROM link WHERE link.`to` = '.$this->db->quote($node_id).' AND `value` >= '.$this->db->quote(LINK_MIN).' ORDER BY `value` DESC LIMIT 50';
        return $this->db->query($query);
    }

	public function autoNode($name) {
        return $this->getNode($this->autoNodeId($name));
	}
	
	public function autoNodeId($name) {
		$query = 'SELECT node.id AS id FROM node '.
			'JOIN link ON (link.`to` = '.AUTONODE.' AND link.relation = '.NODE_SYSTYPE.' AND link.from = node.id) '.
			'WHERE name = '.$this->db->quote($name).' LIMIT 1;';
		$result = $this->db->query($query);
		if (is_array($result) && count($result)) {
			$node = array_pop($result);
			return $node['id'];
		} else {
			$node = new Node();
			$node->setName($name);
			$node->setSystype(AUTONODE);
			$node->save();
			return $node->getId();
		}
	}
	
	public function nodeIds($nodes) {
        $ids = array();
		if ( ! is_array( $nodes ) ) {
			return false;
		}
        foreach ( $nodes as $n ) {
            $ids[] = $n['id'];
        }
        return $ids;
	}
	
	public function search($search_query) {
        $pieces = explode(' ',$search_query);
        $pieces = $this->clean_pieces($pieces);
        $nodes = array();
        foreach ( $pieces as $piece ) {
            $pieceNodes = $this->getByName($piece);
            if ($pieceNodes) {
                $nodes = array_merge($nodes,$pieceNodes);
            } else {
                $nodes[] = array('id' => $this->autoNodeId($piece));
            }
        }
        $this->updateContext($nodes);
        return $this->searchNodes($nodes);
	}
	
	public function searchNodes($nodes) {
        $ids = $this->nodeIds($nodes);
        $query = 'SELECT link.`to` AS id FROM link WHERE link.`from` IN ('.implode(',',$ids).');';
        $results =  $this->db->query($query);
		if ( is_array($results) ) {
			return array_merge($nodes,$results);
		}
		return $nodes;
	}
	
	private function clean_pieces($pieces) {
        $clean = array();
        foreach ($pieces as $piece) {
            if (strlen(trim($piece)) > 2) {
                $clean[] = trim($piece);
            }
        }
        return $clean;
	}
	
	private function updateContext($nodes) {
        return ;
	}
	
	public function getNodeFromUrl($url) {
        $urlObj = $nodes->getOneByName($url);
        if ( ! $urlObj ) {
            // Url node
            $urlObj = new Node();
            $urlObj->setName($url);
            $urlObj->setSystype(URL);
            $urlObj->save();
            
            // Resource node
            $node = new Node();
            $webParser = new Web( $url );
            $node->setName( $webParser->getName() );
            $node->setContent( $webParser->getContent() );
            $node->setSystype( Systype::getSystype( $url ) );
            $node->setUrl( $urlObj->getId() );
        } else {
            $node = $this->getByUrlId( $urlObj->getId() );
        }
        return $node;
	}

}
